package com.cq.hd.order.render.impl;

import com.cq.hd.common.enums.biz.*;
import com.cq.hd.member.api.TbBusinessAgentApi;
import com.cq.hd.member.api.TbConfigSettingApi;
import com.cq.hd.member.api.vo.BusinessPointsMallSettingsVo;
import com.cq.hd.order.api.dto.OrderCommissionDto;
import com.cq.hd.order.render.OrderContext;
import com.cq.hd.order.render.OrderRenderStepEnum;
import com.cq.hd.order.render.dto.AgentInfo;
import com.cq.hd.order.render.dto.PriceDetailDto;
import com.cq.hd.product.api.TbActiveAgentApi;
import com.cq.hd.product.api.vo.ActiveVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.List;
import java.util.Optional;

/**
 * 佣金、积分计算
 *
 * @author much
 * @since 2024/09/13 23:01
 */
@Slf4j
@Component
public class CommissionRender extends AbstractRenderStep {

    @Resource
    private TbBusinessAgentApi businessAgentApi;
    @Resource
    private TbActiveAgentApi activeAgentApi;
    @Autowired
    private TbConfigSettingApi configSettingApi;

    @Override
    public OrderRenderStepEnum step() {
        return OrderRenderStepEnum.COMMISSION;
    }

    @Override
    public void render(OrderContext orderContext) {
        if (orderContext.getAgentInfo() == null) {
            return;
        }
        BusinessPointsMallSettingsVo businessPointsMallSettingsVo = orderContext.getBusinessPointsMallSettingsVo();
        BigDecimal distributionPointsRate = businessPointsMallSettingsVo.getDistribution();
        OrderCommissionDto orderCommissionDto = initCommission(orderContext);
        orderCommissionDto = calOrderCommission(
                orderContext.getAgentInfo(), orderCommissionDto, orderContext.getActiveVo(), distributionPointsRate);
        orderContext.setCommissionDto(orderCommissionDto);
    }

    private OrderCommissionDto initCommission(OrderContext orderContext) {
        OrderCommissionDto orderCommissionDto = new OrderCommissionDto();
        orderCommissionDto.setUserId(orderContext.getUserId());
        PriceDetailDto priceDetailDto = orderContext.getPriceDetailDTO();
        orderCommissionDto.setOrderPrice(priceDetailDto.getOrderPrice());
        orderCommissionDto.setPayPrice(priceDetailDto.getPayPrice());
        orderCommissionDto.setOrderNum(orderContext.getCreateOrderDto().getOrderNum());
        return orderCommissionDto;
    }


    private OrderCommissionDto calOrderCommission(
            AgentInfo agentInfo, OrderCommissionDto orderCommissionDto, ActiveVo activeVo, BigDecimal distributionPointsRate) {
        // 分销开启状态(1-关闭，2-开启)
        if (activeVo.getAgentState().equals(AgentStateEnum.CLOSE.getValue())) {
            return orderCommissionDto;
        }
        // 没有经纪人
        if (agentInfo == null || agentInfo.getAgent1Id() == null || agentInfo.getAgent1Id() <= 0) {
            return orderCommissionDto;
        }

        Long activeId = activeVo.getId();
        Long userId = orderCommissionDto.getUserId();
        BigDecimal orderPrice = orderCommissionDto.getOrderPrice();
        BigDecimal payPrice = orderCommissionDto.getPayPrice();
        Integer orderNum = orderCommissionDto.getOrderNum();


        // TODO 挪到AgentRender
        // 没找到分享码，直接返回
//        ActiveShareRecordVo activeShareRecordVo = activeShareApi.getByCode(code, activeId).unpack();
//        if (activeShareRecordVo == null || activeShareRecordVo.getDelState() != 0) {
//            return orderCommissionDto;
//        }
//        // 推广奖励类型（0-无，1-佣金，2-其他权益，3-积分）
//        Integer rewardType = activeShareRecordVo.getRewardType();
//        if (rewardType == null || rewardType == 0) {
//            return orderCommissionDto;
//        }

        // 推广奖励类型（0-无，1-佣金，2-其他权益，3-积分）
//        Integer rewardType = agentInfo.getRewardType();
        Integer rewardType = activeVo.getRewardType();

        // TODO 挪到AgentRender
        // 如果是经纪人分享给自己下单，也不会有佣金/权益
//        if (activeShareRecordVo.getUserId().equals(userId)) {
//            return orderCommissionDto;
//        }

        Long businessId = activeVo.getBusinessId();
        Long agent1Id = agentInfo.getAgent1Id();
        Long agent2Id = agentInfo.getAgent2Id();

        // 获取商家跟一级经纪人的佣金比例
        BigDecimal exclusiveCommissionRate = businessAgentApi.getAgentCommissionRate(agent1Id, businessId).unpack();
        if (exclusiveCommissionRate == null || exclusiveCommissionRate.compareTo(BigDecimal.ZERO) < 0) {
            return orderCommissionDto;
        }

        // FIXME 可以放在AgentRender判断
        // 是否是所有经纪人可推广：1-是，2-否，如果不是所有经纪人可推广，需要获取活动可推广经纪人出来判断
        if (AgentNumStateEnum.NO.getValue().equals(activeVo.getAgentNumState())) {
            // 查询活动分销经纪人列表
            List<Long> agentIds = activeAgentApi.listByActiveId(activeId).unpack();

            // 判断一级经纪人是否具备分佣权限
            if (CollectionUtils.isEmpty(agentIds) || !agentIds.contains(agent1Id)) {
                return orderCommissionDto;
            }
        }

        // 如果有二级经纪人，需要判断是否有绑定关系及佣金
        BigDecimal subAgentCommissionRate = BigDecimal.ZERO;
        if (agent2Id != null && agent2Id > 0) {
            subAgentCommissionRate = businessAgentApi.getSubAgentCommissionRate(agent2Id, agent1Id).unpack();

            // 没有设置二级佣金，则取默认二级佣金比例
            if (subAgentCommissionRate == null) {
                // 获取默认二级佣金比例
                String defaultLevel2CommissionRate = configSettingApi.getUserConfigValue(
                        agent1Id, ConfigSettingKeyEnum.DEFAULT_LEVEL2_COMMISSION_RATE.name()).unpack();
                if (StringUtils.isEmpty(defaultLevel2CommissionRate)) {
                    return orderCommissionDto;
                } else {
                    subAgentCommissionRate = new BigDecimal(defaultLevel2CommissionRate);
                }
            } else if (subAgentCommissionRate.compareTo(BigDecimal.ZERO) < 0) {
                return orderCommissionDto;
            }

//            if (subAgentCommissionRate == null || subAgentCommissionRate.compareTo(BigDecimal.ZERO) < 0) {
//                return orderCommissionDto;
//            }
        }

        orderCommissionDto.setRewardType(rewardType);
        orderCommissionDto.setAgent1Id(agent1Id);
        orderCommissionDto.setAgent2Id(agent2Id);
        // 经纪人选择推广奖励是其他权益
        if (rewardType == 2) {
            orderCommissionDto.setOtherEquity(activeVo.getOtherEquity());
            return orderCommissionDto;
        }

        // 经纪人选择推广奖励是佣金，则需要查该经纪人的专属佣金数据
        BigDecimal actualCommissionAmt = BigDecimal.ZERO;

        if (exclusiveCommissionRate.compareTo(BigDecimal.ZERO) > 0) {
            orderCommissionDto.setCalCommissionType(CalCommissionTypeEnum.EXCLUSIVE_COMMISSION.getValue());
            orderCommissionDto.setExclusiveCommissionRate(exclusiveCommissionRate);
            // 实际全核销佣金金额=售价*专属佣金比例
            actualCommissionAmt = orderPrice.multiply(exclusiveCommissionRate).divide(new BigDecimal("100"), 2, BigDecimal.ROUND_DOWN);
        } else {
            // 默认佣金类型：0-无，1-佣金，2-佣金比例
            Integer defaultCommissionType = activeVo.getDefaultCommissionType();
            if (defaultCommissionType == null || defaultCommissionType.equals(DefaultCommissionTypeEnum.NULL.getValue())) {
                return orderCommissionDto;
            }

            if (DefaultCommissionTypeEnum.COMMISSION.getValue().equals(defaultCommissionType)) {
                orderCommissionDto.setCalCommissionType(CalCommissionTypeEnum.FIX_COMMISSION.getValue());
                // 实际全核销佣金金额=固定佣金*下单数量
                actualCommissionAmt = activeVo.getCommissionAmt().multiply(new BigDecimal(String.valueOf(orderNum)));
            } else if (DefaultCommissionTypeEnum.COMMISSION_RATE.getValue().equals(defaultCommissionType)) {
                orderCommissionDto.setCalCommissionType(CalCommissionTypeEnum.FIX_COMMISSION_RATE.getValue());
                // 实际全核销佣金金额=售价*固定佣金比例
                actualCommissionAmt = orderPrice.multiply(activeVo.getCommissionRate())
                        .divide(new BigDecimal("100"), 2, RoundingMode.DOWN);
            }
        }

        // 判断实付金额是否小于全核销佣金，如果小于，则全核销佣金=实付金额
        if (payPrice.compareTo(actualCommissionAmt) < 0) {
            actualCommissionAmt = payPrice;
        }
        BigDecimal subAgentCommissionAmt = subAgentCommissionRate.multiply(actualCommissionAmt)
                .divide(BigDecimal.valueOf(100), 2, RoundingMode.DOWN);

        // 如果选择的是积分，需要换算一下
        BigDecimal agentPointsAmt = BigDecimal.ZERO;
        BigDecimal subAgentPointsAmt = BigDecimal.ZERO;
        if (rewardType.equals(RewardTypeEnum.POINTS.getValue())) {
            actualCommissionAmt = BigDecimal.ZERO;
            subAgentCommissionAmt = BigDecimal.ZERO;
            if (agent2Id != null && agent2Id > 0) {
                agentPointsAmt = Optional.ofNullable(activeVo.getRewardPoints()).orElse(BigDecimal.ZERO);
                subAgentPointsAmt = subAgentCommissionRate.multiply(agentPointsAmt).divide(BigDecimal.valueOf(100), 2, BigDecimal.ROUND_DOWN);
//                subAgentPointsAmt = subAgentCommissionAmt.multiply(distributionPointsRate);
//                actualCommissionAmt = actualCommissionAmt.subtract(subAgentCommissionAmt);
//                subAgentCommissionAmt = BigDecimal.ZERO;
            } else {
                agentPointsAmt = Optional.ofNullable(activeVo.getRewardPoints()).orElse(BigDecimal.ZERO);
//                agentPointsAmt = actualCommissionAmt.multiply(distributionPointsRate);
//                actualCommissionAmt = BigDecimal.ZERO;
            }
        }

        orderCommissionDto.setActualCommissionAmt(actualCommissionAmt);
        orderCommissionDto.setSubAgentCommissionRate(subAgentCommissionRate);
        orderCommissionDto.setSubAgentCommissionAmt(subAgentCommissionAmt);
        orderCommissionDto.setAgentPointsAmt(agentPointsAmt);
        orderCommissionDto.setSubAgentPointsAmt(subAgentPointsAmt);
        log.error("orderCommissionDto: {}", orderCommissionDto);

        return orderCommissionDto;
    }

}
